using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using Framework.Interop;

namespace Framework
{
    internal class ExtractIconImpl : IExtractIcon
    {
        private readonly IFolderObject _folderObj;
        private ShellIcon _icon;

        internal ExtractIconImpl(IFolderObject folderObj)
        {
            if (folderObj == null)
            {
                throw new ArgumentNullException("folderObj");
            }

            this._folderObj = folderObj;
        }

        int IExtractIcon.GetIconLocation(ExtractIconOptions uFlags, IntPtr szIconFile, uint cchMax, out int piIndex,
                                         out ExtractIconFlags pwFlags)
        {
            piIndex = -1;
            pwFlags = ExtractIconFlags.None;

            this._icon = this._folderObj.GetIcon((uFlags & ExtractIconOptions.OpenIcon) == ExtractIconOptions.OpenIcon);

            if (this._icon is ShellIcon.FromFile)
            {
                string filename = (this._icon as ShellIcon.FromFile).Filename;
                var data = new byte[cchMax*2];
                Encoding.Unicode.GetBytes(filename, 0, filename.Length, data, 0);
                Marshal.Copy(data, 0, szIconFile, data.Length);

                piIndex = (this._icon as ShellIcon.FromFile).Index;
                pwFlags = this._icon.Flags;
                return 0;
            }
            if (this._icon is ShellIcon.FromIcon)
            {
                pwFlags = this._icon.Flags;
                return 0;
            }
            if (this._icon == null)
            {
                return 1; // use default icon
            }

            Trace.Fail("Unreachable code");
            return 0;
        }

        int IExtractIcon.Extract(string pszFile, uint nIconIndex, out Icon phiconLarge, out Icon phiconSmall,
                                 uint nIconSize)
        {
            phiconLarge = null;
            phiconSmall = null;

            if (this._icon is ShellIcon.FromFile)
            {
                return 1; // caller extracts icon from file
            }
            if (this._icon is ShellIcon.FromIcon)
            {
                var largeSize = (int)(nIconSize & 0x0000FFFF);
                var smallSize = (int)((nIconSize & 0xFFFF0000) >> 16);

                var fi = (ShellIcon.FromIcon)this._icon;
                phiconLarge = new Icon(fi.Icon, largeSize, largeSize);
                phiconSmall = new Icon(fi.Icon, smallSize, smallSize);

                return 0;
            }

            Trace.Fail("Unreachable code");
            return 0;
        }
    } ;
}
